package cn.izeno.wx.models.component

import com.alibaba.fastjson.JSONObject
import com.alibaba.fastjson.annotation.JSONField

/**
 * 授权应用信息
 */
class AppInfo {
  /**
   * 授权方 appid
   */
  var appid: String = ""


  var refreshToken: String = ""

  /**
   * 授权方类型
   * - 0 公众号
   * - 1 小程序
   */
  var miniProgram: Int = 0

  /**
   * 授权方昵称
   */
  var nickName: String = ""

  /**
   * 授权方头像
   */
  var headImg: String = ""

  /**
   * #### 授权方公众号类型，
   * - 0 代表订阅号，
   * - 1 代表由历史老帐号升级后的订阅号，
   * - 2 代表服务号
   */
  var serviceType: Int = 0

  /**
   *
   * 授权方认证类型，
   * - -1 代表未认证，
   * - 0 代表微信认证，
   * - 1 代表新浪微博认证，
   * - 2 代表腾讯微博认证，
   * - 3 代表已资质认证通过、还未通过名称认证，
   * - 4 代表已资质认证通过、还未通过名称认证，但通过了新浪微博认证，
   * - 5 代表已资质认证通过、还未通过名称认证，但通过了腾讯微博认证
   */
  var verifyType: Int = 0

  /**
   * 授权方公众号的原始id
   */
  var userName: String = ""

  /**
   * 授权方公众号设置的微信号，可能为空
   */
  var alias: String = ""

  /**
   * 小程序账号介绍
   */
  var signature: String = ""

  /**
   * 公众号/小程序 主体信息
   */
  var principalName: String = ""

  /**
   * 二维码图片的URL，开发者最好自行也进行保存
   */
  var qrcodeUrl: String = ""

  /**
   * ## 公众号授权给开发者的权限集列表，ID为1到15时分别代表：
   * - 1.消息管理权限
   * - 2.用户管理权限
   * - 3.帐号服务权限
   * - 4.网页服务权限
   * - 5.微信小店权限
   * - 6.微信多客服权限
   * - 7.群发与通知权限
   * - 8.微信卡券权限
   * - 9.微信扫一扫权限
   * - 10.微信连WIFI权限
   * - 11.素材管理权限
   * - 12.微信摇周边权限
   * - 13.微信门店权限
   * - 14.微信支付权限
   * - 15.自定义菜单权限
   *
   * > 请注意： 1）该字段的返回不会考虑公众号是否具备该权限集的权限（因为可能部分具备），请根据公众号的帐号类型和认证情况，来判断公众号的接口权限。
   *
   * ## 小程序授权给开发者的权限集列表，ID为17到19时分别代表：
   * - 17.帐号管理权限
   * - 18.开发管理权限
   * - 19.客服消息管理权限
   * > 请注意： 1）该字段的返回不会考虑小程序是否具备该权限集的权限（因为可能部分具备）。
   *
   */
  var functions: List<Int> = emptyList()

  //<editor-fold desc="miniProgramInfo">
  /**
   * 小程序请求域名
   */
  var requestDomain: List<String> = emptyList()

  var wxRequestDomain: List<String> = emptyList()

  var uploadDomain: List<String> = emptyList()

  var downloadDomain: List<String> = emptyList()

  var bizDomain: List<String> = emptyList()

  var categories: List<String> = emptyList()

  var visitStatus: Int = 0
  //</editor-fold>

  /**
   * 是否开通微信支付功能
   */
  var openPay: Int = 0

  /**
   * 是否开通微信门店功能
   */
  var openStore: Int = 0

  /**
   * 是否开通微信扫商品功能
   */
  var openScan: Int = 0

  /**
   * 是否开通微信卡券功能
   */
  var openCard: Int = 0

  /**
   * 是否开通微信摇一摇功能
   */
  var openShake: Int = 0


  @JSONField(name = "authorizer_info")
  var appInfoJSON: JSONObject? = null
    set(value) {
      if (value == null) return
      this.nickName = value.getString("nick_name").orEmpty()
      this.headImg = value.getString("head_img").orEmpty()
      this.serviceType = value.getJSONObject("service_type_info").getIntValue("id").or(0)
      this.verifyType = value.getJSONObject("verify_type_info").getIntValue("id").or(0)
      this.userName = value.getString("user_name").orEmpty()

      // 小程序时
      this.signature = value.getString("signature").orEmpty()
      this.principalName = value.getString("principal_name").orEmpty()

      // 公众号
      this.alias = value.getString("alias").orEmpty()

      value.getJSONObject("business_info").let {
        this.openPay = it.getIntValue("open_pay").or(0)
        this.openCard = it.getIntValue("open_card").or(0)
        this.openShake = it.getIntValue("open_shake").or(0)
        this.openScan = it.getIntValue("open_scan").or(0)
        this.openStore = it.getIntValue("open_store").or(0)
      }

      this.qrcodeUrl = value.getString("qrcode_url")


      value.getJSONObject("MiniProgramInfo")?.let { mp ->
        mp.getJSONObject("network").let { network ->
          this.requestDomain = network.getJSONArray("RequestDomain").orEmpty().map { it.toString() }
          this.wxRequestDomain = network.getJSONArray("WxRequestDomain").orEmpty().map { it.toString() }
          this.uploadDomain = network.getJSONArray("UploadDomain").orEmpty().map { it.toString() }
          this.downloadDomain = network.getJSONArray("DownloadDomain").orEmpty().map { it.toString() }
          this.bizDomain = network.getJSONArray("BizDomain").orEmpty().map { it.toString() }
        }

        this.categories = mp.getJSONArray("categories").orEmpty()
            .map { cate ->
              val json = cate as JSONObject
              "${json.getString("first")}-${json.getString("second")}"
            }

        this.miniProgram = 1
      }
      field = value
    }

  @JSONField(name = "authorization_info")
  var authInfoJSON: JSONObject? = null
    set(value) {
      if (value == null) return
      this.functions = value.getJSONArray("func_info")
          .map { (it as JSONObject).getJSONObject("funcscope_category").getIntValue("id") }.sorted()

      this.appid = value.getString("authorizer_appid")
      this.refreshToken = value.getString("authorizer_refresh_token")
      field = value
    }
}
